/*This is heavily based on code given to me by OverjoY*/

#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>

#include "tools.h"

char bias_time[22] = "?Y-?M-?D ??:??:??";

typedef struct counterbias_s
{
	u32 tm_sec;
	u32 tm_min;
	u32 tm_hour;
	u32 tm_mday;
	u32 tm_mon;
	u32 tm_year;
	u32 tm_wday;
	u32 tm_yday;
	u32 tm_isdst;
} counterbias;

static bool IsLeapYear(u32 current_year)
{
	u32 yr = 2000;
	while(yr <= current_year)
	{
		if(current_year == yr) return true;
		yr += 4;
	}
	return false;
}

static u32 DaysInMonth(u32 month, u32 year)
{
	switch(month)
	{
		case 0:
		case 2:
		case 4:
		case 6:
		case 7:
		case 9:
		case 11:
			return 31;
			break;
		case 1:
			if(IsLeapYear(year))
				return 29;
			else
				return 28;
			break;
		case 3:
		case 5:
		case 8:
		case 10:
			return 30;
			break;
	}
	return 0;
}

static void MkTime(counterbias *date, u32 time) {
	u32 nmonth, nyear;
	int ndays, tmpdays;

	ndays = time / 86400;
	time -= ndays * 86400;

	date->tm_wday = (ndays + 6) % 7;
	
	nyear = 2000;
	ndays--;
	while(ndays > 365)
	{
		nyear++;
		if(IsLeapYear(nyear))
			ndays -= 366;
		else
			ndays -= 365;
	}
	
	date->tm_year = nyear - 2000;
	date->tm_yday = ndays + 1;

	for(nmonth = 0; nmonth < 11; ++nmonth) 
	{
		tmpdays = ndays - DaysInMonth(nmonth, nyear);
		if(tmpdays < 0)
			break;
			
		ndays = tmpdays;
	}
	
	date->tm_mon = nmonth;
	date->tm_mday = ndays + 1;

	date->tm_hour = time / 3600;
	time -= date->tm_hour * 3600;
	date->tm_min = time / 60;
	date->tm_sec = time - date->tm_min * 60;
	return;
}

void CB2Date(u32 cb) {
	if (!cb) return;
	counterbias *date;
	MkTime(date, cb);
	snprintf(bias_time, MAX_CHARACTERS(bias_time) - 1, "%uY-%uM-%uD %.2u:%.2u:%.2u", date->tm_year, date->tm_mon, date->tm_mday, date->tm_hour, date->tm_min, date->tm_sec);
	return;
}
